import 'package:flutter/material.dart';
import 'package:x3_base_core/x3_base_core.dart';
import 'package:x3_component_core/x3_component_core.dart';
import 'package:x3_form_core/enums/base_advanced_filter_type.dart';
import 'package:x3_form_core/filter_components/base_group_advanced_filter.dart';
import 'package:x3_form_core/models/base_advanced_filter_model.dart';
import 'package:x3_form_core/filter_components/base_advanced_filter.dart';
import 'package:x3_form_core/provider/base_advanced_filter_provider.dart';
import 'package:x3_form_core/filter_components/base_head_advanced_filter.dart';

class BaseFilterUtils {
  /// 底部遮罩的高级筛选弹窗
  static showAdvancedFilter(context, {@required BaseAdvancedFilterProvider baseAdvancedFilterProvider, Function(Map<String, dynamic>) onComplete}) async {
    final size = MediaQuery.of(context).size;
    double height = size.height - 100;
    BaseComponentUtils.buildBottomSheet(context, height: height, child: BaseAdvancedFilter(baseAdvancedFilterProvider: baseAdvancedFilterProvider, onComplete: onComplete));
  }

  /// 顶部遮罩的高级筛选弹窗
  static showHeadAdvancedFilter(context, {@required BaseAdvancedFilterProvider filterProvider, Map<String, dynamic> resetData, double distanceToAppbar, double maxHeight, double minHeight = 200, @required Function(Map<String, dynamic>) onComplete}) async {
    showDialog(context: context, barrierColor: Colors.transparent, builder: (context) => BaseHeadAdvancedFilter(baseAdvancedFilterProvider: filterProvider, distanceToAppbar: distanceToAppbar, resetData: resetData, maxHeight: maxHeight == null ? MediaQuery.of(context).size.height * 0.5 : maxHeight, onComplete: onComplete));
  }

  /// 底部分组高级筛选弹窗
  static showGroupAdvancedFilter(context, {@required List<String> groupTitleList, @required List<BaseAdvancedFilterProvider> filterProviderList, @required Function(Map<String, dynamic>) onComplete, double sheetHeight}) async {
    final size = MediaQuery.of(context).size;
    double height = sheetHeight == null ? size.height * 3 / 5 : sheetHeight;
    BaseComponentUtils.buildBottomSheet(
      context,
      height: height,
      child: BaseGroupAdvancedFilter(onComplete: onComplete, groupTitleList: groupTitleList, filterProviderList: filterProviderList),
    );
  }

  /// 获取入参BaseAdvancedFilterProvider
  static Future<BaseAdvancedFilterProvider> getBaseAdvancedFilterProvider(String appApiUrlId, {Map<String, dynamic> Function(BaseHttpRequestModel requestModel) otherParamEvent, List<BaseHttpRequestModel> defaultRequests = const []}) async {
    List<BaseHttpRequestModel> requests = BaseUtils.isNotEmpty(appApiUrlId) ? await dioUtil.fetchRequestParams(appApiUrlId) : defaultRequests;
    List<BaseAdvancedFilterModel> filterItems = await BaseFilterUtils._getFilterItems(requests, otherParamEvent: otherParamEvent);
    return new BaseAdvancedFilterProvider(models: filterItems, dataSource: {});
  }

  static Future<List<BaseAdvancedFilterModel>> _getFilterItems(List<BaseHttpRequestModel> requests, {Map<String, dynamic> Function(BaseHttpRequestModel requestModel) otherParamEvent}) async {
    List<BaseHttpRequestModel> filterItems = [];
    for (int i = 0; i < requests.length; i++) {
      BaseHttpRequestModel filterItem = await BaseFilterUtils._getFilterItem(requests[i]);
      filterItems.add(filterItem);
    }
    return requests.map((e) => BaseFilterUtils._getAdvancedFilterItem(e, otherParamEvent: otherParamEvent)).toList();
  }

  static BaseAdvancedFilterModel _getAdvancedFilterItem(BaseHttpRequestModel data, {Map<String, dynamic> Function(BaseHttpRequestModel requestModel) otherParamEvent}) {
    BaseAdvancedFilterType inputType = BaseFilterUtils._initAdvancedFilterType( data );
    Map<String, dynamic> otherParam = {};
    if (otherParamEvent != null) otherParam = otherParamEvent(data);
    return new BaseAdvancedFilterModel(fieldName: data.fieldName, inputType: inputType, name: data.name, note: data.notes, hidden: false, selectData: data.selectData, otherParam: otherParam);
  }

  static Future<BaseHttpRequestModel> _getFilterItem(BaseHttpRequestModel request) async {
    List<BaseHttpInputTypeEnum> inputTypes = [BaseHttpInputTypeEnum.Checkbox, BaseHttpInputTypeEnum.Radio];
    if (!inputTypes.contains(request.inputType)) return Future.value(request);
    BaseHttpResultModel result = await dioUtil.fetch(request.inputApi, method: BaseHttpMethodEnum.GET);
    List<dynamic> resultItems = result.data;
    request.selectData = resultItems.map((dynamic resultItem) => BaseKeyValueModel.fromJson(resultItem)).toList();
    return request;
  }

  static BaseAdvancedFilterType _initAdvancedFilterType( BaseHttpRequestModel request ) {
    if ( request.inputType == BaseHttpInputTypeEnum.Checkbox ) return BaseAdvancedFilterType.MultipleChoice;
    if ( request.inputType == BaseHttpInputTypeEnum.Radio ) return BaseAdvancedFilterType.SingleChoice;
    if ( request.inputType == BaseHttpInputTypeEnum.InputSearch && BaseUtils.isNotEmpty( request.inputApi ) ) return BaseAdvancedFilterType.InputSearchMultipleChoice;
    if ( request.inputType == BaseHttpInputTypeEnum.InputDateRange ) return BaseAdvancedFilterType.InputDateRange;
    return BaseAdvancedFilterType.InputText;
  }
}
